package com.cencat.order.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cencat.order.entity.RouteInvoice;
import com.cencat.order.vo.RouteInvoiceVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 线路发票数据访问层接口
 * 
 * @author cencat
 * @date 2024-01-20
 */
@Mapper
public interface RouteInvoiceMapper extends BaseMapper<RouteInvoice> {

    /**
     * 分页查询发票列表
     *
     * @param page 分页参数
     * @param invoiceCode 发票编号(模糊查询)
     * @param invoiceType 发票类型
     * @param invoiceStatus 发票状态
     * @param routeId 路线ID
     * @param driverId 司机ID
     * @param vehicleId 车辆ID
     * @param merchantId 商家ID
     * @param startTime 创建开始时间
     * @param endTime 创建结束时间
     * @return 发票分页列表
     */
    IPage<RouteInvoiceVO> selectInvoicePage(Page<RouteInvoiceVO> page,
                                          @Param("invoiceCode") String invoiceCode,
                                          @Param("invoiceType") String invoiceType,
                                          @Param("invoiceStatus") Integer invoiceStatus,
                                          @Param("routeId") Long routeId,
                                          @Param("driverId") Long driverId,
                                          @Param("vehicleId") Long vehicleId,
                                          @Param("merchantId") Long merchantId,
                                          @Param("startTime") LocalDateTime startTime,
                                          @Param("endTime") LocalDateTime endTime);

    /**
     * 根据发票编号查询发票信息
     *
     * @param invoiceCode 发票编号
     * @return 发票信息
     */
    RouteInvoiceVO selectByInvoiceCode(@Param("invoiceCode") String invoiceCode);

    /**
     * 根据路线ID查询发票列表
     *
     * @param routeId 路线ID
     * @param invoiceStatus 发票状态
     * @return 发票列表
     */
    List<RouteInvoiceVO> selectByRouteId(@Param("routeId") Long routeId,
                                       @Param("invoiceStatus") Integer invoiceStatus);

    /**
     * 根据司机ID查询发票列表
     *
     * @param driverId 司机ID
     * @param invoiceStatus 发票状态
     * @param startTime 查询开始时间
     * @param endTime 查询结束时间
     * @return 发票列表
     */
    List<RouteInvoiceVO> selectByDriverId(@Param("driverId") Long driverId,
                                        @Param("invoiceStatus") Integer invoiceStatus,
                                        @Param("startTime") LocalDateTime startTime,
                                        @Param("endTime") LocalDateTime endTime);

    /**
     * 根据车辆ID查询发票列表
     *
     * @param vehicleId 车辆ID
     * @param invoiceStatus 发票状态
     * @param startTime 查询开始时间
     * @param endTime 查询结束时间
     * @return 发票列表
     */
    List<RouteInvoiceVO> selectByVehicleId(@Param("vehicleId") Long vehicleId,
                                         @Param("invoiceStatus") Integer invoiceStatus,
                                         @Param("startTime") LocalDateTime startTime,
                                         @Param("endTime") LocalDateTime endTime);

    /**
     * 根据商家ID查询发票列表
     *
     * @param merchantId 商家ID
     * @param invoiceStatus 发票状态
     * @param startTime 查询开始时间
     * @param endTime 查询结束时间
     * @return 发票列表
     */
    List<RouteInvoiceVO> selectByMerchantId(@Param("merchantId") Long merchantId,
                                          @Param("invoiceStatus") Integer invoiceStatus,
                                          @Param("startTime") LocalDateTime startTime,
                                          @Param("endTime") LocalDateTime endTime);

    /**
     * 查询发票统计信息
     *
     * @param routeId 路线ID
     * @param driverId 司机ID
     * @param vehicleId 车辆ID
     * @param merchantId 商家ID
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 统计信息
     */
    Map<String, Object> selectInvoiceStatistics(@Param("routeId") Long routeId,
                                               @Param("driverId") Long driverId,
                                               @Param("vehicleId") Long vehicleId,
                                               @Param("merchantId") Long merchantId,
                                               @Param("startTime") LocalDateTime startTime,
                                               @Param("endTime") LocalDateTime endTime);

    /**
     * 更新发票状态
     *
     * @param invoiceId 发票ID
     * @param invoiceStatus 发票状态
     * @param updateTime 更新时间
     * @param remark 备注
     * @return 更新行数
     */
    int updateInvoiceStatus(@Param("invoiceId") Long invoiceId,
                           @Param("invoiceStatus") Integer invoiceStatus,
                           @Param("updateTime") LocalDateTime updateTime,
                           @Param("remark") String remark);

    /**
     * 更新发票审核状态
     *
     * @param invoiceId 发票ID
     * @param auditStatus 审核状态
     * @param auditTime 审核时间
     * @param auditUserId 审核人ID
     * @param auditRemark 审核备注
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int updateAuditStatus(@Param("invoiceId") Long invoiceId,
                         @Param("auditStatus") Integer auditStatus,
                         @Param("auditTime") LocalDateTime auditTime,
                         @Param("auditUserId") Long auditUserId,
                         @Param("auditRemark") String auditRemark,
                         @Param("updateTime") LocalDateTime updateTime);

    /**
     * 更新发票支付状态
     *
     * @param invoiceId 发票ID
     * @param paymentStatus 支付状态
     * @param paymentTime 支付时间
     * @param paymentMethod 支付方式
     * @param paymentAmount 支付金额
     * @param transactionId 交易流水号
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int updatePaymentStatus(@Param("invoiceId") Long invoiceId,
                           @Param("paymentStatus") Integer paymentStatus,
                           @Param("paymentTime") LocalDateTime paymentTime,
                           @Param("paymentMethod") String paymentMethod,
                           @Param("paymentAmount") BigDecimal paymentAmount,
                           @Param("transactionId") String transactionId,
                           @Param("updateTime") LocalDateTime updateTime);

    /**
     * 更新发票金额信息
     *
     * @param invoiceId 发票ID
     * @param totalAmount 总金额
     * @param taxAmount 税额
     * @param discountAmount 优惠金额
     * @param actualAmount 实际金额
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int updateInvoiceAmount(@Param("invoiceId") Long invoiceId,
                           @Param("totalAmount") BigDecimal totalAmount,
                           @Param("taxAmount") BigDecimal taxAmount,
                           @Param("discountAmount") BigDecimal discountAmount,
                           @Param("actualAmount") BigDecimal actualAmount,
                           @Param("updateTime") LocalDateTime updateTime);

    /**
     * 更新发票开票信息
     *
     * @param invoiceId 发票ID
     * @param invoiceNumber 发票号码
     * @param invoiceDate 开票日期
     * @param invoiceUrl 发票文件URL
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int updateInvoiceInfo(@Param("invoiceId") Long invoiceId,
                         @Param("invoiceNumber") String invoiceNumber,
                         @Param("invoiceDate") LocalDateTime invoiceDate,
                         @Param("invoiceUrl") String invoiceUrl,
                         @Param("updateTime") LocalDateTime updateTime);

    /**
     * 更新发票收票信息
     *
     * @param invoiceId 发票ID
     * @param receiptStatus 收票状态
     * @param receiptTime 收票时间
     * @param receiptUserId 收票人ID
     * @param receiptRemark 收票备注
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int updateReceiptInfo(@Param("invoiceId") Long invoiceId,
                         @Param("receiptStatus") Integer receiptStatus,
                         @Param("receiptTime") LocalDateTime receiptTime,
                         @Param("receiptUserId") Long receiptUserId,
                         @Param("receiptRemark") String receiptRemark,
                         @Param("updateTime") LocalDateTime updateTime);

    /**
     * 批量更新发票状态
     *
     * @param invoiceIds 发票ID列表
     * @param invoiceStatus 发票状态
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int batchUpdateInvoiceStatus(@Param("invoiceIds") List<Long> invoiceIds,
                                @Param("invoiceStatus") Integer invoiceStatus,
                                @Param("updateTime") LocalDateTime updateTime);

    /**
     * 批量更新发票审核状态
     *
     * @param invoiceIds 发票ID列表
     * @param auditStatus 审核状态
     * @param auditTime 审核时间
     * @param auditUserId 审核人ID
     * @param auditRemark 审核备注
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int batchUpdateAuditStatus(@Param("invoiceIds") List<Long> invoiceIds,
                              @Param("auditStatus") Integer auditStatus,
                              @Param("auditTime") LocalDateTime auditTime,
                              @Param("auditUserId") Long auditUserId,
                              @Param("auditRemark") String auditRemark,
                              @Param("updateTime") LocalDateTime updateTime);

    /**
     * 查询发票收入统计
     *
     * @param driverId 司机ID
     * @param vehicleId 车辆ID
     * @param merchantId 商家ID
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 收入统计信息
     */
    Map<String, Object> selectIncomeStatistics(@Param("driverId") Long driverId,
                                              @Param("vehicleId") Long vehicleId,
                                              @Param("merchantId") Long merchantId,
                                              @Param("startTime") LocalDateTime startTime,
                                              @Param("endTime") LocalDateTime endTime);

    /**
     * 查询发票税务统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @param invoiceType 发票类型
     * @return 税务统计信息
     */
    Map<String, Object> selectTaxStatistics(@Param("startTime") LocalDateTime startTime,
                                           @Param("endTime") LocalDateTime endTime,
                                           @Param("invoiceType") String invoiceType);

    /**
     * 查询发票支付统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @param paymentMethod 支付方式
     * @return 支付统计信息
     */
    Map<String, Object> selectPaymentStatistics(@Param("startTime") LocalDateTime startTime,
                                               @Param("endTime") LocalDateTime endTime,
                                               @Param("paymentMethod") String paymentMethod);

    /**
     * 查询发票审核统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @param auditUserId 审核人ID
     * @return 审核统计信息
     */
    Map<String, Object> selectAuditStatistics(@Param("startTime") LocalDateTime startTime,
                                             @Param("endTime") LocalDateTime endTime,
                                             @Param("auditUserId") Long auditUserId);

    /**
     * 查询发票类型分布统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 类型分布统计信息
     */
    List<Map<String, Object>> selectInvoiceTypeDistributionStatistics(@Param("startTime") LocalDateTime startTime,
                                                                      @Param("endTime") LocalDateTime endTime);

    /**
     * 查询发票状态分布统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 状态分布统计信息
     */
    List<Map<String, Object>> selectInvoiceStatusDistributionStatistics(@Param("startTime") LocalDateTime startTime,
                                                                        @Param("endTime") LocalDateTime endTime);

    /**
     * 查询发票金额区间分布统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 金额区间分布统计信息
     */
    List<Map<String, Object>> selectInvoiceAmountRangeDistributionStatistics(@Param("startTime") LocalDateTime startTime,
                                                                            @Param("endTime") LocalDateTime endTime);

    /**
     * 查询发票处理时效统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 处理时效统计信息
     */
    Map<String, Object> selectInvoiceProcessingTimeStatistics(@Param("startTime") LocalDateTime startTime,
                                                             @Param("endTime") LocalDateTime endTime);

    /**
     * 查询发票异常统计
     *
     * @param startTime 统计开始时间
     * @param endTime 统计结束时间
     * @return 异常统计信息
     */
    Map<String, Object> selectInvoiceExceptionStatistics(@Param("startTime") LocalDateTime startTime,
                                                        @Param("endTime") LocalDateTime endTime);

    /**
     * 查询发票质量评估
     *
     * @param startTime 评估开始时间
     * @param endTime 评估结束时间
     * @return 质量评估信息
     */
    Map<String, Object> selectInvoiceQualityAssessment(@Param("startTime") LocalDateTime startTime,
                                                      @Param("endTime") LocalDateTime endTime);

    /**
     * 查询发票合规性检查
     *
     * @param invoiceId 发票ID
     * @return 合规性检查结果
     */
    Map<String, Object> selectInvoiceComplianceCheck(@Param("invoiceId") Long invoiceId);

    /**
     * 查询发票风险评估
     *
     * @param invoiceId 发票ID
     * @return 风险评估信息
     */
    Map<String, Object> selectInvoiceRiskAssessment(@Param("invoiceId") Long invoiceId);

    /**
     * 查询发票重复性检查
     *
     * @param invoiceCode 发票编号
     * @param invoiceNumber 发票号码
     * @param totalAmount 总金额
     * @return 重复性检查结果
     */
    List<RouteInvoiceVO> selectInvoiceDuplicateCheck(@Param("invoiceCode") String invoiceCode,
                                                    @Param("invoiceNumber") String invoiceNumber,
                                                    @Param("totalAmount") BigDecimal totalAmount);

    /**
     * 查询发票关联订单信息
     *
     * @param invoiceId 发票ID
     * @return 关联订单信息
     */
    List<Map<String, Object>> selectInvoiceRelatedOrders(@Param("invoiceId") Long invoiceId);

    /**
     * 查询发票关联路线信息
     *
     * @param invoiceId 发票ID
     * @return 关联路线信息
     */
    Map<String, Object> selectInvoiceRelatedRoute(@Param("invoiceId") Long invoiceId);

    /**
     * 查询发票关联司机信息
     *
     * @param invoiceId 发票ID
     * @return 关联司机信息
     */
    Map<String, Object> selectInvoiceRelatedDriver(@Param("invoiceId") Long invoiceId);

    /**
     * 查询发票关联车辆信息
     *
     * @param invoiceId 发票ID
     * @return 关联车辆信息
     */
    Map<String, Object> selectInvoiceRelatedVehicle(@Param("invoiceId") Long invoiceId);

    /**
     * 查询发票关联商家信息
     *
     * @param invoiceId 发票ID
     * @return 关联商家信息
     */
    Map<String, Object> selectInvoiceRelatedMerchant(@Param("invoiceId") Long invoiceId);

    /**
     * 软删除发票信息
     *
     * @param invoiceId 发票ID
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int softDeleteInvoice(@Param("invoiceId") Long invoiceId,
                         @Param("updateTime") LocalDateTime updateTime);

    /**
     * 批量软删除发票信息
     *
     * @param invoiceIds 发票ID列表
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int batchSoftDeleteInvoices(@Param("invoiceIds") List<Long> invoiceIds,
                               @Param("updateTime") LocalDateTime updateTime);

    /**
     * 恢复已删除的发票信息
     *
     * @param invoiceId 发票ID
     * @param updateTime 更新时间
     * @return 更新行数
     */
    int restoreInvoice(@Param("invoiceId") Long invoiceId,
                      @Param("updateTime") LocalDateTime updateTime);

    /**
     * 查询发票操作日志
     *
     * @param invoiceId 发票ID
     * @param startTime 查询开始时间
     * @param endTime 查询结束时间
     * @param limit 查询数量限制
     * @return 操作日志列表
     */
    List<Map<String, Object>> selectInvoiceOperationLogs(@Param("invoiceId") Long invoiceId,
                                                        @Param("startTime") LocalDateTime startTime,
                                                        @Param("endTime") LocalDateTime endTime,
                                                        @Param("limit") Integer limit);
}